<?php
namespace app\api\service;

use app\api\model\Order;
use app\lib\exception\OrderEx;
use app\lib\enum\OrderStatus;
use app\lib\exception\PremEx;
use think\Loader;
use think\Log;
use app\lib\exception\WxEx;

/** 
* Document
*/

Loader::import('WxPay.WxPay',EXTEND_PATH,'.Api.php');
class Pay {
    private $orderID;
    private $orderNO;

    public function __construct($orderID) {
        if (empty($orderID)) {
            throw new Exception('订单号不能为空');
        }
        
        $this->orderID = $orderID;
    }

    public function pay(){
        $uid = Token::getCacheValue(Token::getFromHttp(),'uid');
        # 订单检测
        $order = Order::initById($this->orderID);
        // 合法性检测（是否存在、是否当前用户的订单）
        if(empty($order)) 
            throw new OrderEx('订单不存在',60001);  // 订单不存在
        if(! $order->checkOwner($uid)) 
            throw new OrderEx('非法操作',60003); // 不是当前用户的订单
        // 状态检测(是否待支付状态)
        if(! $order->checkInStatus(OrderStatus::UnPayed)) 
            throw new OrderEx('订单状态异常',60004);
        // 库存检测
        if(! $order->checkInStock()){
            // throw new OrderEx('订单商品库存不足',60002); // 订单库存不足
            $orderInfo = $order->getOrderInfo();
            $resData = $orderInfo['items'];
            return $this->data($resData,'缺货',403,60002);
        }
        $this->orderNO = $order->order_no;
        // 拼接微信预订单请求
        $wxPayData = $this->makeWxPreOrder($order->total_price);
        // 拼接微信预订单请求
        $wxOrder = $this->getPaySignature($wxPayData);
        // 将prepay_id存到数据库
        $order->prepay_id = $wxOrder['prepay_id'];
        $order->save();
        $signValues = $this->sign($wxOrder);

        return $signValues;
    }

    /**
     * 拼接微信预订单请求
     *
     * @param float $totalPrice 订单总价格
     * @return \WxPayUnifiedOrder
     */
    private function makeWxPreOrder($totalPrice){
        $openid = Token::getCacheValue(Token::getFromHttp(),'openid');
        if (! $openid) throw new PremEx('登录超时',40001);

        $wxPayData = new \WxPayUnifiedOrder();
        $wxPayData->SetOut_trade_no($this->orderNO);
        $wxPayData->SetTrade_type('JSAPI');
        $wxPayData->SetTotal_fee($totalPrice*100);
        $wxPayData->SetBody('tpShop');
        $wxPayData->SetOpenid($openid);
        $wxPayData->SetNotify_url(''); // TODO 微信回调接口
        return $wxPayData;
    }

    /**
     * 拼接微信预订单请求
     *
     * @param \WxPayUnifiedOrder $wxPayData
     * @return 
     */
    private function getPaySignature($wxPayData){
        $wxOrder = \WxPayApi::unifiedOrder($wxPayData);
        if ($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] != 'SUCCESS') {
            Log::error($wxOrder);
            Log::error('获取支付订单失败');
            throw new WxEx("获取支付订单失败");
        }
        return $wxOrder;
    }

    private function sign($wxOrder){
        $jsApiPayData = new \WxPayJsApiPay();
        $jsApiPayData->SetAppid(config('wx.app_id'));
        $jsApiPayData->SetTimeStamp((string) time());
        $rand = md5(time().mt_rand(1,1000));
        $jsApiPayData->SetNonceStr($rand);
        $jsApiPayData->SetPackage('prepay_id='.$wxOrder['prepay_id']);
        $jsApiPayData->SetSignType('md5');
        $sign = $jsApiPayData->MakeSign();
        $rawValues = $jsApiPayData->GetValues();
        $rawValues['paySign'] = $sign;
        unset($rawValues['appId']);

        return $rawValues;
    }

    
}